/*
	PlAr is Platform Arena: a 2D multiplayer shooting game
	Copyright (c) 2010, Antonio Ragagnin <spocchio@gmail.com>
	All rights reserved.

	This file is licensed under the New BSD License.
*/

package demo;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Transparency;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.SocketException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.imageio.stream.FileImageInputStream;
import javax.swing.JFrame;
import javax.swing.JOptionPane;

import org.jbox2d.common.Vec2;

import plar.ClientServer.Client;
import plar.ClientServer.ShownElement;
import plar.core.Common;
import plar.core.KeyFlag;
import plar.core.Sprite;

/**
*
* @author Antonio Ragagbabau
*/
public class client extends javax.swing.JFrame {
	static final long serialVersionUID = 1L;
	/** Creates new form JClient */

	int index = 0;
	long lastRefresh = 0;
	public KeyFlag premuti;
	public String clientusage;
	public HashMap<String, BufferedImage> bufferedImages;
	BufferedImage bufferedImage;
	Point resolution;
	public static Client c;
	int delay = 0;
	int framerate=20;
	String remaningTime="";
	private String messaggi="*";

	public static void main(String args[]) throws IOException {

		int port = Common.port;
		Common.intro();
		String s = Common.ask(
		"Welcome to "+Common.clientName+" v"+Common.version+" \n\n Insert the server network adress [Default: localhost] ");
		
		if(s.equals("")) s="localhost";
		Common.info(1,"host=["+s+"]");
		String res="none";
		try {
			c = new Client();

		} catch (SocketException ex) {
			ex.printStackTrace();
			JOptionPane.showMessageDialog(null, "ERROR: Unable to connect to "
			+ s);
			System.exit(0);

		}
		try {
			res = c.connect(s, Common.port);
			c.welcome();
			Common.info(1,"Connected to "+s+ " - "+res);

		} catch (IOException ex) {
			ex.printStackTrace();
			JOptionPane.showMessageDialog(null, "ERROR: Unable to connect to "
			+ s);
			System.exit(0);
		} catch (ClassNotFoundException ex) {
			ex.printStackTrace();
			JOptionPane.showMessageDialog(null, "ERROR: Unable to connect to "
			+ s);
			System.exit(0);
		}


		Common.info(1,"1.");
		c.step();
		
		String type = Common.ask(c.getMOTD());
		
		String name =
		Common.ask(
		"Please insert a nickname: ");
		c.start();
		try {
			c.setPlayer(name, type);
		} catch (IOException ex) {
			ex.printStackTrace();

		}
		java.awt.EventQueue.invokeLater(new Runnable() {
			public void run() {
				client cl = new client();
				cl.setVisible(true);

			}
		});


	}

	public client() {
		super();
		Common.info(7, "new client()");
		initComponents();
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		premuti = new KeyFlag((short) 0);
		bufferedImages = new HashMap<String, BufferedImage>();
		clientusage=Common.product + " v" + Common.version + "\n\n"+
		"       to RUN use ARROWS or A,D keys\n"+
		"       to JUMP use UP key or SPACE or W\n"+
		"       to BEND use DOWN or S key\n"+
		"       to use the SPECIAL SKILLS use ALT or ALT GR key\n"+
		"       to AIM'n'FIRE use the MOUSE\n"+
		"       to change GUN use NUMBER keys\n"+
		"       to CHAT use C key\n";
		this.addMouseListener(new java.awt.event.MouseListener() {


			public void mouseClicked(MouseEvent e) {
				requestFocus();
			}

			public void mouseEntered(MouseEvent e) {
				requestFocus();
			}

			public void mouseExited(MouseEvent e) {
			}

			public void mousePressed(MouseEvent e) {

				double x = e.getX();
				double y = c.resolution.y - e.getY();
				x -= c.resolution.x / 2;
				y -= c.resolution.y / 2 ;
				double mod = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2));
				x /= mod;
				y /= mod;

				// x/=c.resolution.x/2;
				// y/=c.resolution.y/2;

				if (!premuti.check(KeyFlag.FIRE)) {
					premuti.add(KeyFlag.FIRE);
				}
				try {
					c.setDirection(x, -y);
				} catch (IOException ex) {
					Logger.getLogger(client.class.getName()).log(Level.SEVERE,
					null, ex);
				}

			}

			public void mouseReleased(MouseEvent e) {
			}
		});

		this.addKeyListener(new java.awt.event.KeyListener() {
			public void keyPressed(KeyEvent e) {
				if ((e.getKeyCode() == KeyEvent.VK_C)) {


					String str = Common.ask("chat: ");

					try {
						c.chat(str);
					} catch (IOException ex) {
						ex.printStackTrace();
					}

				}

				// premuti.add("special");
				if (e.getKeyCode() == KeyEvent.VK_F1)
				Common.message(clientusage,false,false);

				if (e.getKeyCode() == KeyEvent.VK_1
						&& !premuti.check(KeyFlag.k1))
				premuti.add(KeyFlag.k1);
				if (e.getKeyCode() == KeyEvent.VK_2
						&& !premuti.check(KeyFlag.k2))
				premuti.add(KeyFlag.k2);
				if (e.getKeyCode() == KeyEvent.VK_3
						&& !premuti.check(KeyFlag.k3))
				premuti.add(KeyFlag.k3);

				if ((e.getKeyCode() == KeyEvent.VK_SPACE
							|| e.getKeyCode() == KeyEvent.VK_UP || e.getKeyCode() == KeyEvent.VK_W))
				premuti.add(KeyFlag.JUMP);
				if ((e.getKeyCode() == KeyEvent.VK_RIGHT || e.getKeyCode() == KeyEvent.VK_D))
				premuti.add(KeyFlag.RIGHT);
				if ((e.getKeyCode() == KeyEvent.VK_DOWN || e.getKeyCode() == KeyEvent.VK_S))
				premuti.add(KeyFlag.DOWN);
				if ((e.getKeyCode() == KeyEvent.VK_LEFT || e.getKeyCode() == KeyEvent.VK_A))
				premuti.add(KeyFlag.LEFT);
				if ((e.getKeyCode() == KeyEvent.VK_ALT || e.getKeyCode() == KeyEvent.VK_ALT_GRAPH))
				premuti.add(KeyFlag.SPECIAL);

			}

			public void keyReleased(KeyEvent e) {
				// if (e.isAltDown())
				// premuti.remove("special");
				if (e.getKeyCode() == KeyEvent.VK_1)
				premuti.del(KeyFlag.k1);
				if (e.getKeyCode() == KeyEvent.VK_2)
				premuti.del(KeyFlag.k2);
				if (e.getKeyCode() == KeyEvent.VK_3)
				premuti.del(KeyFlag.k3);
				if (e.getKeyCode() == KeyEvent.VK_UP
						|| e.getKeyCode() == KeyEvent.VK_SPACE
						|| e.getKeyCode() == KeyEvent.VK_W)
				premuti.del(KeyFlag.JUMP);
				if (e.getKeyCode() == KeyEvent.VK_RIGHT
						|| e.getKeyCode() == KeyEvent.VK_D)
				premuti.del(KeyFlag.RIGHT);
				if (e.getKeyCode() == KeyEvent.VK_LEFT
						|| e.getKeyCode() == KeyEvent.VK_A)
				premuti.del(KeyFlag.LEFT);

				if (e.getKeyCode() == KeyEvent.VK_DOWN
						|| e.getKeyCode() == KeyEvent.VK_S)
				premuti.del(KeyFlag.DOWN);
				if (e.getKeyCode() == KeyEvent.VK_ALT
						|| e.getKeyCode() == KeyEvent.VK_ALT_GRAPH)
				premuti.del(KeyFlag.SPECIAL);

			}

			public void keyTyped(KeyEvent e) {
			}
		});

		class autoupdateGUI extends Thread {

			public void run() {
				try {
					long a, b, delay;

					while (c.isConnected) {
						a = Calendar.getInstance().getTimeInMillis();
						try {
							viewOutput();
						} catch (IOException ex) {
							Logger.getLogger(client.class.getName()).log(
							Level.SEVERE, null, ex);
						}
						b = Calendar.getInstance().getTimeInMillis();
						delay = b - a;
						if (delay < framerate)
						Thread.sleep(framerate - delay);
						delay = (int) delay;
						repaint();




					}
					JOptionPane.showMessageDialog(null, "ERROR: Connection timeout");
					System.exit(0);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				// System.exit(0);
			}
		}

		class autoSEND extends Thread {

			public void run() {
				try {
					KeyFlag lastPremuti = new KeyFlag();
					while (true) {
						// Common.info("lastPremuti:"+lastPremuti+" premuti:"+premuti.toString());
						// if(premuti.size()>0 || (premuti.size()==0 &&
						// !lastPremuti.equals(premuti.toString())))
						try {
							c.sendInput(premuti);
						} catch (IOException ex) {
							ex.printStackTrace();

							lastPremuti = premuti;
						}

						if (premuti.check(KeyFlag.FIRE))
						premuti.del(KeyFlag.FIRE);
						// premuti.clear();
						Thread.sleep(23);

					}

				} catch (InterruptedException e) {
					e.printStackTrace();
				}

				// System.exit(0);
			}
		}
		resolution = c.resolution;
		Thread tGUI = new autoupdateGUI();
		tGUI.setName("Thread gui");
		System.out.println("Thread in esecuzione: " + tGUI);
		tGUI.start();
		Thread tSEND = new autoSEND();
		tSEND.start();

		this.setSize(c.resolution.x, c.resolution.y);

	}

	public int frames;

	public void viewOutput() throws IOException {
		// Common.info(7,"GUI REQUEST SCREEN UPDATE");
		c.updateScreenAndSprites();

		frames++;
		index++;
		if (frames >= 20) {
			frames = 0;
			c.getChat();
			if(!c.getServerM().equals(""))
			{
				Common.message(c.getServerM(),false,false);
				c.clearServerM();
			}
			
            messaggi = c.getMessages();
			long t = c.remaning;
			Calendar cal = Calendar.getInstance();
			cal.setTimeInMillis(t);

			int minuti = cal.get(Calendar.MINUTE);
			int secondi = cal.get(Calendar.SECOND);
			remaningTime = "["+minuti+":"+secondi+"]";
			
		}
		
		

	}

	// @SuppressWarnings("unchecked")
	// <editor-fold defaultstate="collapsed"
	// desc="Generated Code">//GEN-BEGIN:initComponents
	private void initComponents() {

	}// </editor-fold>//GEN-END:initComponents

	/**
	* @param args
	*            the command line arguments
	*/

	void play() {

	}

	public void paint(Graphics g) {

		long thistime = java.util.Calendar.getInstance().getTimeInMillis();
		long delta = thistime - lastRefresh;
		lastRefresh = thistime;

		Graphics2D g3 = (Graphics2D) g;
		GraphicsDevice gd = GraphicsEnvironment.getLocalGraphicsEnvironment()
		.getDefaultScreenDevice();
		GraphicsConfiguration gc = gd.getDefaultConfiguration();
		if (bufferedImage == null)
		bufferedImage = gc.createCompatibleImage(resolution.x,
		resolution.y, Transparency.OPAQUE);

		Graphics2D g2 = bufferedImage.createGraphics();
		g2.setColor(new Color(30, 40, 50));
		Rectangle new_rect = new Rectangle(0, 0, resolution.x, resolution.y);
		g2.fill(new_rect);

		g2.setColor(Color.cyan);
		// Common.info(1, "--------------> viewving "+screen.size());
		if (c.getScreen() == null || c.getScreen().size() == 0)
		return;
		
		for (int i=0;i<c.getScreen().size();i++) {
			ShownElement se = null;
			try{
				se = c.getScreen().get(i);
			}catch(Exception ex)
			{
				Common.info(1," schermo modificato in concorrenza.");
				ex.printStackTrace();
			}
			
			if (se != null && se.spriteSet.size() > 0) {
				Sprite currentSprite = se.spriteSet.getFromIndex(index,framerate);

				BufferedImage fungoImg = null;
				if (bufferedImages.containsKey(currentSprite.getFileName()))
				fungoImg = bufferedImages.get(currentSprite.getFileName());
				else {

					try {

						File file1 = new File(currentSprite.getFileName());
						Common.info(
						1,
						"JClient::paint() loading "
						+ file1.getAbsolutePath());
						FileImageInputStream fImg = new FileImageInputStream(
						file1);
						fungoImg = ImageIO.read(fImg);
					} catch (FileNotFoundException e) {
						Common.info(5,
						"error loading: " + currentSprite.getFileName());
					} catch (IOException e) {
						Common.info(5,
						"error loading: " + currentSprite.getFileName());
					}
					if (fungoImg != null)

					{
						bufferedImages.put(currentSprite.getFileName(),
						fungoImg);
						//Common.info(1, "loaded: " + currentSprite.getFileName());
					} else
					Common.info(1, "il funghetto e' nul" + File.listRoots());
				}
				Vec2 scale = c.scale;
				Point position = new Point(
				(int) (se.position.x + (currentSprite.offsetx - currentSprite.sizex / 2)
				* scale.x),
				(int) (se.position.y + (currentSprite.offsety - currentSprite.sizey / 2)
				* scale.y));
				Point size = new Point((int) (currentSprite.sizex * scale.x),
				(int) (currentSprite.sizey * scale.y));
				g2.rotate(se.theta, position.x + size.x / 2, position.y
				+ size.y / 2);
				//g2.draw(new Rectangle(position.x, position.y, size.x, size.y));
				g2.drawImage(fungoImg, position.x, position.y, size.x, size.y,
				this);
				g2.rotate(-se.theta, (position.x + size.x / 2),
				(position.y + size.y / 2));
			}
		}

		/*
			int w = 12;
			int s = 55;
			g2.drawString(Common.product + " v" + Common.version + " "
					, 10, s - 5);
			g2.drawString("       to RUN use ARROWS or A,D keys", 10, s + w);
			g2.drawString("       to JUMP use UP key or SPACE or W", 10, s + w * 2);
			g2.drawString("       to BEND use DOWN or S key", 10, s + w * 3);
			g2.drawString("       to use SPECIAL SKILLS use ALT or ALT GR key", 10,
					s + w * 4);
			g2.drawString("       to AIM'n'FIRE use MOUSE", 10, s + w * 5);
			g2.drawString("       to change GUN use NUMBERS", 10, s + w * 6);
			g2.drawString("       to CHAT use C key", 10, s + w * 7);
				*/
		String[] chats = messaggi.split("\\n");
		int b=10;
		int j = 3;

		g2.drawString(Common.product + " v" + Common.version+", framerate: " + (delta) + "ms, delay: " + delay,10, b + j * 11);
		j++;
		j++;
		g2.drawString("Please press F1 for the keys guide.", 10,  b + j * 11);
		j++;
		j++;
		g2.drawString("Time: "+remaningTime, 10, b + j * 11);
		j++;
		g2.drawString("Life: "+c.life, 10, b + j * 11);
		j++;
		g2.drawString("Score: "+c.score, 10, b + j * 11);
		j++;
		g2.drawString("Spawns: "+c.spawns, 10, b + j * 11);
		j++;
		g2.drawString("Guns: "+c.getGuns(), 10,  b + j * 11);
		j++;
		j++;
		g2.drawString("Chat: ", 10,  b + j * 11);
		j++;


		for (int i = 0; i < chats.length; i++) {
			g2.drawString(chats[i], 10, b + j * 11);
			// if(chats[i].length()>1)
			j++;
		}



		// g2.drawString("Created by "+Common.author+" "+Common.copyright, 10,
		// 170);
		//g2.drawString("Chat:"+chats, 10, 200);
		g3.drawImage(bufferedImage, null, 0, 0);
	}

	// Variables declaration - do not modify//GEN-BEGIN:variables
	private javax.swing.JPanel jPanel1;
	// End of variables declaration//GEN-END:variables

}
